using System.Globalization;
using System.IO;
using EnvDTE;
using Microsoft.Practices.RecipeFramework;
using Microsoft.VisualStudio.Shell;
using VSSDKAssist.Assets.Actions.Base;
using VSSDKAssist.Assets.Actions.General;
using VSSDKAssist.Assets.Actions.VisualStudio;
using VSSDKAssist.Assets.Helpers;
using VSShellAssist.Recipes.Common.Helpers;
using System;

namespace VSShellAssist.Recipes.CreatePkgdef
{
	/// <summary>
	/// Action thats creates a pkgdef file for a VS Package
	/// </summary>
    public class CreatePkgdefAction : ActionBase
	{
        #region Properties
        [Input(Required = true)]
        public Project Project { get; set; }

        [Input(Required = true)]
        public CodeClass CodeClass { get; set; }

        [Input(Required = true)]
        public Type ClassType { get; set; }

        [Input(Required = true)]
        public RegistrationMethod RegistrationMethod { get; set; }
        #endregion

        #region Protected Implementation
        /// <summary>
        /// Called when [execute].
        /// </summary>
        protected override void OnExecute()
        {
            string outputPath = this.Project.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value.ToString();
            string buildPath = this.Project.Properties.Item("LocalPath").Value.ToString();
            string targetName = this.Project.Properties.Item("OutputFileName").Value.ToString();
            string assemblyFile = Path.Combine(buildPath, Path.Combine(outputPath, targetName));
            string projectPath = Path.GetDirectoryName(this.Project.Properties.Item("FullPath").Value.ToString());
            string pkgdefFile = this.CodeClass.Name;

            if(File.Exists(assemblyFile))
            {
                using(ExecuteProcessAction executeProcessAction = new ExecuteProcessAction())
                {
                    executeProcessAction.Site = this.Site;
                    executeProcessAction.FileName =
                            Path.Combine(
                                Path.Combine(
                                    VSShellAssist.Recipes.Common.Helpers.CommonHelper.GetVSSdkInstallPath(),
                                    VSShellAssist.Recipes.Common.Helpers.Constants.VSSdkToolRelPath),
                                    VSShellAssist.Recipes.Common.Helpers.Constants.RegPkgTool);

                    executeProcessAction.Arguments = GetArguments(assemblyFile, projectPath, ref pkgdefFile);

                    if(File.Exists(pkgdefFile) &&
                        VSIPHelper.FindItemByName(
                            this.Project.ProjectItems,
                            Path.GetFileName(pkgdefFile),
                            false) != null)
                    {
                        TFSHelper.CheckOutFile(VisualStudio, pkgdefFile);

                        executeProcessAction.Execute();
                    }
                    else
                    {
                        executeProcessAction.Execute();

                        using(AddItemFromFileToProjectAction addItemFromFileToProjectAction = new AddItemFromFileToProjectAction())
                        {
                            addItemFromFileToProjectAction.Site = this.Site;
                            addItemFromFileToProjectAction.Project = this.Project;
                            addItemFromFileToProjectAction.SourceFileName = pkgdefFile;

                            addItemFromFileToProjectAction.Execute();
                        }
                    }

                    if(this.RegistrationMethod == RegistrationMethod.CodeBase)
                    {
                        DefFileWriter defWriter = new DefFileWriter(pkgdefFile);

                        defWriter.WriteValue(
                            string.Format(@"$RootKey$\Packages\{0}", ClassType.GUID.ToString("B")),
                            "CodeBase",
                            string.Format(@"$PackageFolder$\{0}", Path.GetFileName(assemblyFile)));
                    }
                }
            }
        }

        private string GetArguments(string assemblyFile, string projectPath, ref string pkgdefFile)
        {
            string arguments = string.Empty;
            string sanitizicedFile;

            if(assemblyFile.Contains(" "))
            {
                assemblyFile = string.Concat("\"", assemblyFile, "\"");
            }

            switch(this.RegistrationMethod)
            {
                case RegistrationMethod.Assembly:
                    arguments += "/assembly ";
                    break;
                case RegistrationMethod.CodeBase:
                    arguments += "/codebase ";
                    break;
                case RegistrationMethod.Default:
                    break;
                default:
                    break;
            }

            pkgdefFile =
                Path.Combine(projectPath,
                    string.Concat(pkgdefFile, Properties.Resources.PkgDefExtension));

            sanitizicedFile = pkgdefFile;

            if(sanitizicedFile.Contains(" "))
            {
                sanitizicedFile = string.Concat("\"", sanitizicedFile, "\"");
            }

            arguments +=
                string.Format(
                    CultureInfo.CurrentCulture,
                    "/pkgdeffile:{0} {1}",
                    sanitizicedFile,
                    assemblyFile);

            return arguments;
        }
        #endregion

    }
}